﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Dynamic;
using System.Data.Entity;
using BugTracker.DataAccess.Data;

namespace BugTracker.BusinessLogic.Project
{
    public class ProjectService : IProjectService
    {
        private BugTrackerEntities db = null;
        private IProjectMapper mapper = null;

        public ProjectService(BugTrackerEntities db, ProjectMapper mapper)
        {
            if (db == null)
                throw new ArgumentNullException("db");
            if (mapper == null)
                throw new ArgumentNullException("mapper");
            this.db = db;
            this.mapper = mapper;
        }

        #region IDataService<Project> Members

        public IList<BusinessEntities.Entities.Project.Project> Load()
        {
            IList<BusinessEntities.Entities.Project.Project> collection = null;
            var results = (from models in db.Projects 
                           where models.IsActive == true &
                           models.IsDeleted == false select models);
            if(results != null)
            {
                collection = new List<BusinessEntities.Entities.Project.Project>();
                foreach(var item in results)
                    collection.Add(mapper.Map(item));

            }
            return collection;
        }

        public IList<BusinessEntities.Entities.Project.Project> LoadIncludeInactive()
        {
            IList<BusinessEntities.Entities.Project.Project> collection = null;
            var results = (from models in db.Projects  
                           where models.IsDeleted == false select models);
            if(results != null)
            {
                collection = new List<BusinessEntities.Entities.Project.Project>();
                foreach(var item in results)
                    collection.Add(mapper.Map(item));

            }
            return collection;
        }

        public IList<BusinessEntities.Entities.Project.Project> Page(int pageIndex, int pageSize, out int count)
        {
            IList<BusinessEntities.Entities.Project.Project> collection = null;
            count = this.Count();
            var results = (from models in db.Projects 
                           where models.IsActive == true & models.IsDeleted == false
                           select models).Skip(pageIndex * pageSize).Take(pageSize);
            if (results != null)
            {
                collection = new List<BusinessEntities.Entities.Project.Project>();
                foreach (var item in results)
                    collection.Add(mapper.Map(item));
            }
            return collection;
        }

        public IList<BusinessEntities.Entities.Project.Project> PageSort(
                                            int pageIndex, int pageSize, 
                                            string sortColumn, 
                                            string sortDirection, out int count)
        {
            IList<BusinessEntities.Entities.Project.Project> collection = null;
            count = this.Count();
            var results = (from models in db.Projects 
                           where models.IsActive == true & models.IsDeleted == false
                           select models)
                           .OrderBy("it." + sortColumn + " " + sortDirection)
                           .Skip(pageIndex * pageSize)
                           .Take(pageSize);
            if (results != null)
            {
                collection = new List<BusinessEntities.Entities.Project.Project>();
                foreach (var item in results)
                    collection.Add(mapper.Map(item));
            }
            return collection;
        }

        public IList<BusinessEntities.Entities.Project.Project> PageSortWhere(
                                                int pageIndex, int pageSize, 
                                                string sortColumn, string sortDirection, 
                                                string whereColumn, string whereClause, out int count)
        {
            IList<BusinessEntities.Entities.Project.Project> collection = null;
            count = this.Count();
            var results = (from models in db.Projects 
                           where models.IsActive == true & models.IsDeleted == false
                           select models)
                           .Where("it." + whereColumn + " " + whereClause)
                           .OrderBy("it." + sortColumn + " " + sortDirection)
                           .Skip(pageIndex * pageSize)
                           .Take(pageSize);
            if (results != null)
            {
                collection = new List<BusinessEntities.Entities.Project.Project>();
                foreach (var item in results)
                    collection.Add(mapper.Map(item));
            }
            return collection;
        }

        public BusinessEntities.Entities.Project.Project LoadById(int id)
        {
            var results =  (from models in db.Projects 
                    where models.ProjectID == id & models.IsActive == true & models.IsDeleted == false
                    select models).FirstOrDefault();
            return mapper.Map(results);
        }

        public BusinessEntities.Entities.Project.Project LoadByGuid(Guid guid)
        {
            var results = (from models in db.Projects 
                    where models.RowGuid == guid & models.IsActive == true & models.IsDeleted == false
                    select models).FirstOrDefault();
            return mapper.Map(results);
        }

        public int Count()
        {
            return (from models in db.Projects  
                           where models.IsActive == true &
                           models.IsDeleted == false select models).Count();
        }

        public int CountIncludeInactive()
        {
            return (from models in db.Projects 
                    where models.IsDeleted == false
                    select models).Count();
        }

        public bool HasChanged(int id)
        {
            return ((from models in db.Projects 
                    where models.ProjectID == id & models.IsActive == true & models.IsDeleted == false
                    select models.ModifiedOn).Cast<DateTime>().First() > DateTime.Now);
        }

        public bool HasChanged(Guid guid)
        {
            return ((from models in db.Projects 
                     where models.RowGuid == guid & models.IsActive == true & models.IsDeleted == false
                     select models.ModifiedOn).Cast<DateTime>().First() > DateTime.Now);
        }

        public void MakeInactive(BusinessEntities.Entities.Project.Project value)
        {
            var results = (from models in db.Projects 
                             where models.ProjectID == value.ProjectID & 
                             models.IsActive == true & 
                             models.IsDeleted == false
                             select models).First();
            if(results != null)
            {
                results.IsActive = false;
                db.SaveChanges();
            }
        }

        public void InsertObject(BusinessEntities.Entities.Project.Project value)
        {
            db.Projects .AddObject(mapper.Map(value));
            db.SaveChanges();
        }

        public void UpdateObject(BusinessEntities.Entities.Project.Project value)
        {
            var model = (from models in db.Projects 
                         where models.ProjectID == value.ProjectID &
                         models.IsActive == true &
                         models.IsDeleted == false
                         select models).First();
            if (model != null)
            {
                mapper.Map(model, value);
                db.SaveChanges();
            }
        }

        public void DeleteObject(BusinessEntities.Entities.Project.Project value)
        {
            var results = (from models in db.Projects 
                           where models.ProjectID == value.ProjectID &
                           models.IsActive == true &
                           models.IsDeleted == false
                           select models).First();
            if (results != null)
            {
                results.IsDeleted = true;
                db.SaveChanges();
            }
        }

        public void DeleteObject(int id)
        {
            var results = (from models in db.Projects 
                           where models.ProjectID == id &
                           models.IsActive == true &
                           models.IsDeleted == false
                           select models).First();
            if (results != null)
            {
                results.IsDeleted = true;
                db.SaveChanges();
            }
        }

        public void DeleteObject(Guid guid)
        {
            var results = (from models in db.Projects 
                           where models.RowGuid == guid &
                           models.IsActive == true &
                           models.IsDeleted == false
                           select models).First();
            if (results != null)
            {
                results.IsDeleted = true;
                db.SaveChanges();
            }
        }

        public bool HasDuplicate(BusinessEntities.Entities.Project.Project value)
        {
            var results = (from models in db.Projects
                           where models.Name == value.Name &
                           models.IsActive == true &
                           models.IsDeleted == false
                           select models).First();
            return (results == null) ? false : true;
        }

        #endregion
    }
}
